package com.songcha.sakura.mvvm.setting

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.songcha.library_base.base.BaseFragment
import com.songcha.library_common.helper.SharedPreferenceHelper
import com.songcha.library_common.ui.dialog.ListDialog
import com.songcha.library_common.util.LogUtil
import com.songcha.library_common.util.ToastUtil
import com.songcha.library_common.util.dp2px
import com.songcha.sakura.config.BaseConfig
import com.songcha.sakura.databinding.FragmentSettingBinding
import io.reactivex.Observable
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import org.libtorrent4j.*
import org.libtorrent4j.alerts.*
import org.libtorrent4j.swig.libtorrent
import org.libtorrent4j.swig.torrent_flags_t
import java.io.File
import java.nio.file.Files.find
import java.util.*


class SettingFragment : BaseFragment() {
    companion object{
        val TAG:String= SettingFragment::class.java.simpleName
    }
    private var _binding: FragmentSettingBinding? = null

    private val binding get() = _binding!!

    private val INNER_LISTENER_TYPES = intArrayOf(
        AlertType.ADD_TORRENT.swig(),
        AlertType.STATE_CHANGED.swig(),
        AlertType.TORRENT_FINISHED.swig(),
        AlertType.TORRENT_REMOVED.swig(),
        AlertType.TORRENT_PAUSED.swig(),
        AlertType.TORRENT_RESUMED.swig(),
        AlertType.SAVE_RESUME_DATA.swig(),
        AlertType.STORAGE_MOVED.swig(),
        AlertType.STORAGE_MOVED_FAILED.swig(),
        AlertType.METADATA_RECEIVED.swig(),
        AlertType.PIECE_FINISHED.swig(),
        AlertType.READ_PIECE.swig(),
        AlertType.TORRENT_ERROR.swig(),
        AlertType.METADATA_FAILED.swig(),
        AlertType.FILE_ERROR.swig(),
        AlertType.FASTRESUME_REJECTED.swig(),
        AlertType.TORRENT_CHECKED.swig(),
    )


    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {

        _binding = FragmentSettingBinding.inflate(inflater, container, false)

        _binding!!.edtBaseUrl.setText(BaseConfig.BASE_URL)
        setEdtFontName()


        _binding!!.btnSetBaseUrl.setOnClickListener{
            SharedPreferenceHelper.setString("setting","base_url",  _binding!!.edtBaseUrl.text.toString())
            ToastUtil.show("设置成功，重启生效")
        }

        _binding!!.sakuraBtnMagnet.setOnClickListener{
            //fetchMagnet("magnet:?xt=urn:btih:18bccd6ce28b6e25f2b831d6e2dd147aa9a3fc99&tr=http%3a%2f%2ft.nyaatracker.com%2fannounce&tr=http%3a%2f%2ftracker.kamigami.org%3a2710%2fannounce&tr=http%3a%2f%2fshare.camoe.cn%3a8080%2fannounce&tr=http%3a%2f%2fopentracker.acgnx.se%2fannounce&tr=http%3a%2f%2fanidex.moe%3a6969%2fannounce&tr=http%3a%2f%2ft.acg.rip%3a6699%2fannounce&tr=https%3a%2f%2ftr.bangumi.moe%3a9696%2fannounce&tr=udp%3a%2f%2ftr.bangumi.moe%3a6969%2fannounce&tr=http%3a%2f%2fopen.acgtracker.com%3a1096%2fannounce&tr=udp%3a%2f%2ftracker.opentrackr.org%3a1337%2fannounce")
            if(_binding!!.sakuraEdtMagnet.text.toString().trim().isBlank()) return@setOnClickListener
            fetchMagnet(_binding!!.sakuraEdtMagnet.text.toString().trim())
        }

        _binding!!.sakuraBtnFont.setOnClickListener{
            //SharedPreferenceHelper.setString("setting","base_url",  _binding!!.edtBaseUrl.text.toString())
            //ToastUtil.show("设置成功，重启生效")
            val pathList= mutableListOf<String>()
            val nameList= mutableListOf<String>()

            val files=requireActivity().getExternalFilesDir("font")!!.listFiles()
            if(files==null){
                ToastUtil.show("没有找到字体")
                return@setOnClickListener
            }
            for(file in files){
                pathList.add(file.absolutePath)
                nameList.add(file.name)
            }

            if(nameList.size==0) {
                ToastUtil.show("没有找到字体")
                return@setOnClickListener
            }

            val dialog= ListDialog(requireContext(),nameList)
            dialog.apply {
                setDialogTitle("选择字体")
                setOnListDialogItemClickListener{p->
                    val path=pathList[p]
                    BaseConfig.FONT_PATH=path
                    setEdtFontName()
                    SharedPreferenceHelper.setString("setting","font_path",  path)
                    ToastUtil.show("已更改字体")
                    return@setOnListDialogItemClickListener true
                }
            }
            dialog.show()
            /*DialogHelper.showListDialog(it.context,"选择字体",nameList){ p->
                val path=pathList[p]
                BaseConfig.FONT_PATH=path
                setEdtFontName()
                SharedPreferenceHelper.setString("setting","font_path",  path)
                ToastUtil.show("已更改字体")
                true
            }*/
        }

        return binding.root
    }

    override fun isNeedShowLoadingDialog(): Boolean {
        return true
    }

    class TorrentFileItem(val fileSize:Long=0L,val str:String=""){
    }

    private var mSession:SessionManager?=null
    private var mTorrentBytes:ByteArray?=null
    private var mMagnetSize=0
    private var mFileName=""
    private var mTorrentHandle:TorrentHandle?=null

    private fun fetchMagnet(magnetUrl:String){
        Observable.create<MutableList<TorrentFileItem>> {
            mSession=SessionManager()
            mSession!!.start()

            mTorrentBytes=mSession!!.fetchMagnet(magnetUrl,30, File("."))
            if(mTorrentBytes==null) {
                it.onError(Throwable())
                return@create
            }
            val entry= Entry.bdecode(mTorrentBytes)

            val a=entry.dictionary()
            mFileName=a.get("name").toString()
            val e=a.get("info")!!.dictionary().get("files")!!.list()
            mMagnetSize=e.size

            val list= mutableListOf<TorrentFileItem>()
            for(item in e){
                val info=item.dictionary().get("path")!!.list()
                val length=item.dictionary().get("length")!!.toString().toLong()

                val sb=StringBuilder()
                sb.append((length/1024/1024).toString()+"MB")
                sb.append(" ")
                for(itemInfo in info){
                    sb.append(itemInfo.toString())
                    sb.append(" ")
                }
                list.add(TorrentFileItem(length,sb.toString()))
            }
            it.onNext(list)
            it.onComplete()
        }.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object :Observer<MutableList<TorrentFileItem>>{
                override fun onSubscribe(d: Disposable) {
                    showLoadingDialog(false)
                }

                override fun onError(e: Throwable) {
                    ToastUtil.show("获取失败")
                    hideLoadingDialog()
                }

                override fun onComplete() {
                    hideLoadingDialog()
                }

                override fun onNext(t: MutableList<TorrentFileItem>) {
                    val list= mutableListOf<String>()
                    t.map {
                        list.add(it.str)
                    }
                    val dialog=ListDialog(requireContext(),list)
                    dialog.setDialogTitle("磁链文件")
                    dialog.setHeight(400.dp2px())
                    dialog.setOnListDialogItemClickListener{p->

                        if(mFileName.isNullOrBlank()) return@setOnListDialogItemClickListener true

                        val fileSize=t[p].fileSize
                        mTorrentHandle=null

                        val priorities = arrayOfNulls<Priority>(mMagnetSize)
                        Arrays.fill(priorities,Priority.IGNORE)
                        priorities[p]=Priority.DEFAULT
                        val saveFile=requireContext().getExternalFilesDir("video")

                        showLoadingDialog(false)

                        mSession!!.download(TorrentInfo.bdecode(mTorrentBytes),saveFile,null,priorities,null, torrent_flags_t())
                        
                        mSession!!.addListener(object : AlertListener {
                            override fun types(): IntArray {
                                return INNER_LISTENER_TYPES
                            }

                            override fun alert(alert: Alert<*>?) {
                                val type = alert!!.type()
                                //LogUtil.log("aaa alert",type)
                                when (type) {
                                    AlertType.ADD_TORRENT->{

                                    }
                                    AlertType.STATE_CHANGED -> {
                                        if(mTorrentHandle==null){
                                            val torrentAlert = alert as TorrentAlert<*>
                                            mTorrentHandle = mSession!!.find(torrentAlert.handle().infoHash())
                                        }

                                    }
                                    AlertType.TORRENT_FINISHED -> {
                                        //downloadedSize=0L
                                        hideLoadingDialog()
                                        ToastUtil.show("下载完成")
                                    }
                                    AlertType.TORRENT_REMOVED -> {

                                    }
                                    AlertType.TORRENT_PAUSED -> {}
                                    AlertType.TORRENT_RESUMED -> {}

                                    AlertType.STORAGE_MOVED -> {}
                                    AlertType.STORAGE_MOVED_FAILED -> {}
                                    AlertType.PIECE_FINISHED -> {
                                        if(mTorrentHandle==null) return
                                        if (mTorrentHandle!!.isValid) {
                                            //mTorrentHandle!!.saveResumeData(TorrentHandle.SAVE_INFO_DICT)
                                            //val totalDone=mTorrentHandle!!.status().totalDone()
                                            //LogUtil.log("aaa PIECE_FINISHED",progress,(progress*100).toInt())
                                            requireActivity().runOnUiThread {
                                                val progress=mTorrentHandle!!.status().progress()
                                                setLoadingDialogProgress((progress*100).toInt())
                                            }

                                        }
                                       //val a = alert as PieceFinishedAlert
                                       //LogUtil.log("aaa PIECE_FINISHED",a.pieceIndex())
                                    }
                                    AlertType.SAVE_RESUME_DATA -> {
                                       /* alert as SaveResumeDataAlert

                                        val bytes = libtorrent.write_resume_data(alert.params().swig()).bencode()
                                        downloadedSize+=bytes.size
                                        val progress=((downloadedSize/(fileSize*1.0f))*100)
                                        LogUtil.log("aaa",downloadedSize,fileSize,progress)
                                        setLoadingDialogProgress(progress.toInt())*/
                                    }
                                    AlertType.METADATA_RECEIVED -> {

                                    }
                                    AlertType.READ_PIECE -> {
                                        // LogUtil.log("aaa READ_PIECE")
                                    }
                                    AlertType.TORRENT_CHECKED -> {}
                                    else -> {}
                                }
                            }

                        })

                        return@setOnListDialogItemClickListener true
                    }
                    dialog.show()
                }

            })









    }

    private fun setEdtFontName(){
        if(BaseConfig.FONT_PATH.isNotEmpty()){
            val index=BaseConfig.FONT_PATH.lastIndexOf("/")
            _binding!!.sakuraEdtFont.setText(BaseConfig.FONT_PATH.substring(index+1))
        }
    }


    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}